package com.shouxin.attendance.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.shouxin.attendance.R;
import com.shouxin.attendance.constants.CommonConstants;
import com.shouxin.attendance.constants.PrefKey;
import com.shouxin.attendance.database.DBHelper;
import com.shouxin.attendance.database.dao.BabyCustodyDao;
import com.shouxin.attendance.database.dao.BabyDao;
import com.shouxin.attendance.database.dao.ClazzDao;
import com.shouxin.attendance.database.dao.CustodyDao;
import com.shouxin.attendance.database.model.Baby;
import com.shouxin.attendance.database.model.BabyCustody;
import com.shouxin.attendance.database.model.Clazz;
import com.shouxin.attendance.database.model.Custody;
import com.shouxin.attendance.event.EventCardNumber;
import com.shouxin.attendance.network.CommonCallback;
import com.shouxin.attendance.network.HttpAction;
import com.shouxin.attendance.network.ServiceFactory;
import com.shouxin.attendance.serialport.SendHelper;
import com.shouxin.attendance.service.BackgroundService;
import com.shouxin.attendance.service.CheckRun;
import com.shouxin.attendance.utils.HandleSwipeCard;
import com.shouxin.attendance.utils.SharedPref;
import com.shouxin.attendance.utils.ThreadPool;
import com.shouxin.attendance.utils.UIUtils;
import com.shouxin.attendance.utils.Utils;
import com.shouxin.attendance.view.BabyInfoView;

import org.apache.log4j.Logger;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import okhttp3.Call;
import okhttp3.Response;

public class MainActivity extends BaseActivity {

    private static final Logger logger = Logger.getLogger(MainActivity.class);

    private HashMap<String, BabyInfoView> mBabyViewMap = new HashMap<>();

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
                logger.debug("Receive android.net.conn.CONNECTIVITY_CHANGE message.");
                ConnectivityManager connectManager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);

                NetworkInfo networkInfo = connectManager.getActiveNetworkInfo();
                // 网络连接
                if (networkInfo != null && networkInfo.isConnected()) {
                    logger.debug("mobileNetwork is connected.");
                    BackgroundService.getInstance().networkConnected(true);
                    ThreadPool.execute(new CheckRun(context.getApplicationContext()));
                    return;
                }

                boolean noConnect = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                if (noConnect) {
                    logger.debug("Oh o o...no network is available.");
                    BackgroundService.getInstance().networkConnected(false);
                }
            }
        }
    };

    @Subscribe(threadMode = ThreadMode.ASYNC)
    @SuppressWarnings("unused")
    public void onEventMainThread(final EventCardNumber event) {
        logger.debug("EventCardNumber...event =>" + event);

        handlerCardMsg(event.getPort(), event.getCardNumber(), event.getState(), event.getTimeStamp());
    }

    private void handlerCardMsg(final String port, String cardNumber, final int state, long time) {
        // 判断是否刷消警卡
        Set<String> disAlarmCards = SharedPref.getSetString(PrefKey.SET_CARD_NUMBER);
        if (disAlarmCards != null && disAlarmCards.contains(cardNumber)) {
            logger.debug("正在刷消警卡...");
            SendHelper.getInstance().sendAlarmCloseCmd(port);
            return;
        }
        // 正常出入校刷卡
        final Custody custody = DBHelper.getInstance().getCustodyDao().queryBuilder().where(CustodyDao.Properties.Card.eq(cardNumber)).unique();
        if (custody != null) {
            logger.debug("家长刷卡，忽略...");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mBabyViewMap.get(port).setCustody(custody);
                }
            });
            return;
        }
        final Baby baby = DBHelper.getInstance().getBabyDao().queryBuilder().where(BabyDao.Properties.Card.eq(cardNumber)).unique();
        if (baby == null) {
            logger.error("找不到信息，请检查卡片合法性！");
            // 告警命令发送
            SendHelper.getInstance().sendAlarmOpenCmd(port);
            return;
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mBabyViewMap.get(port).resetViews();
                mBabyViewMap.get(port).setBabyInfo(state, baby);
            }
        });
        // 记录刷卡记录
        HandleSwipeCard.get().addSwipeInfo(baby, cardNumber, time, state);
    }

    @Override
    public void setContentView() {
        setContentView(R.layout.activity_main);
    }

    @Override
    public void initUIViews() {
        mBabyViewMap.put(CommonConstants.PORT_1, (BabyInfoView) findViewById(R.id.port_one));
        mBabyViewMap.put(CommonConstants.PORT_2, (BabyInfoView) findViewById(R.id.port_two));
        mBabyViewMap.put(CommonConstants.PORT_3, (BabyInfoView) findViewById(R.id.port_three));
        mBabyViewMap.put(CommonConstants.PORT_4, (BabyInfoView) findViewById(R.id.port_four));
    }

    @Override
    public void initData() {
        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(mReceiver, intentfilter);

        if (SharedPref.getBoolean(PrefKey.FIRST_LOGIN, true)) {
            SharedPref.putBoolean(PrefKey.FIRST_LOGIN, false);
            updateConfig();
        }

        Utils.wakeUpAndUnlock(this);

        BackgroundService.getInstance().initLocalPushData();

        loadNurseryData();
    }

    /**
     * 更新配置
     */
    private void updateConfig() {
        HttpAction httpAction = ServiceFactory.get().getService(HttpAction.NAME);
        if (httpAction == null) {
            logger.error("HttpAction is null");
            return;
        }
        String token = SharedPref.getString(PrefKey.TOKEN, "");
        if (TextUtils.isEmpty(token)) {
            logger.error("Invalid token!");
            return;
        }

        HashMap<String, String> requestParams = new HashMap<>();
        requestParams.put("ver", Utils.getAppVersionName());
        requestParams.put("client", "1");
        requestParams.put("token", token);

        httpAction.getConfig(requestParams, this, new CommonCallback() {

            @Override
            public void onFailure(Call call, IOException e) {
                super.onFailure(call, e);
                logger.debug("同步进出配置失败！");
                mHandler.sendMessage(mHandler.obtainMessage(SHOW_TOAST, "同步进出配置失败！"));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.debug("getConfig response :" + response.body().string());
                logger.debug("同步进出配置成功！");
                mHandler.sendMessage(mHandler.obtainMessage(SHOW_TOAST, "同步进出配置成功！"));
            }
        });
    }

    @Override
    public void bindEvents() {
    }

    private void clearAllAlarm() {
        SendHelper.getInstance().sendAlarmCloseCmd(CommonConstants.PORT_1);
        SystemClock.sleep(100);
        SendHelper.getInstance().sendAlarmCloseCmd(CommonConstants.PORT_2);
        SystemClock.sleep(100);
        SendHelper.getInstance().sendAlarmCloseCmd(CommonConstants.PORT_3);
        SystemClock.sleep(100);
        SendHelper.getInstance().sendAlarmCloseCmd(CommonConstants.PORT_4);
    }

    @Override
    protected void initToolbar() {

    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.nav_history) {
            startActivity(new Intent(this, HistoryActivity.class));
        }
        /*else if (id == R.id.nav_update_version) {
            checkUpdate();
		}*/
        else if (id == R.id.nav_upload) {
            startActivity(new Intent(this, UploadActivity.class));
        } else if (id == R.id.nav_logout) {
            SharedPref.putString(PrefKey.ACCOUNT, "");
            SharedPref.putString(PrefKey.PASSWORD, "");
            SharedPref.putBoolean(PrefKey.AUTO_LOGIN, false);
            UIUtils.toast("注销成功！");
            startActivity(new Intent(this, LoginActivity.class));
        } else if (id == R.id.nav_about) {
            startActivity(new Intent(this, AboutActivity.class));
        } else if (id == R.id.nav_clear_alarm) {
            startActivity(new Intent(this, ClearAlarmActivity.class));
        } else if (id == R.id.nav_manual_clear_alarm) {
            clearAllAlarm();
        } else if (id == R.id.nav_update_config) {
            updateConfig();
        }
        return true;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main_drawer, menu);
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        EventBus.getDefault().unregister(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
    }

    @Override
    protected void onDestroy() {
        if (mReceiver != null) {
            unregisterReceiver(mReceiver);
        }
        super.onDestroy();
    }

    private void loadNurseryData() {
        UIUtils.showLoading(this, "正在加载幼儿园数据...");
        String token = SharedPref.getString(PrefKey.TOKEN, "");
        if (TextUtils.isEmpty(token)) {
            logger.error("Invalid token!");
            UIUtils.dismiss();
            return;
        }
        HashMap<String, String> requestParams = new HashMap<>();
        requestParams.put("ver", Utils.getAppVersionName());
        requestParams.put("token", token);

        String updateTime = SharedPref.getString(PrefKey.UPDATE_TIME, "");
        requestParams.put("update_at", updateTime);

        HttpAction httpAction = ServiceFactory.get().getService(HttpAction.NAME);
        if (httpAction == null) {
            logger.error("HttpAction is null");
            return;
        }
        logger.debug("request params =>" + requestParams);
        httpAction.getBabyList(requestParams, this, new CommonCallback() {
            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                mHandler.sendEmptyMessage(DIALOG_DISMISS);
                handleBabyResp(JSON.parseObject(response.body().string()));
            }

            @Override
            public void onFailure(Call call, IOException e) {
                super.onFailure(call, e);
                mHandler.sendEmptyMessage(DIALOG_DISMISS);
                mHandler.sendMessage(mHandler.obtainMessage(SHOW_TOAST, "幼儿园数据初始化失败，请重新登录！"));
            }
        });
    }

    private void handleBabyResp(JSONObject response) {
        logger.debug("response =>" + response.toJSONString());
        int ret = response.getIntValue("ret");
        if (ret != 0) {
            logger.error("获取学生列表失败...");
            UIUtils.toast("获取学生列表失败，请重启应用！");
            return;
        }
        JSONObject data = response.getJSONObject("data");
        SharedPref.putString(PrefKey.UPDATE_TIME, data.getString("update_at"));

        JSONArray clazzs = data.getJSONArray("class");
        List<Clazz> clazzList = JSON.parseArray(clazzs.toJSONString(), Clazz.class);
        logger.debug("clazzList =>" + clazzList);
        ClazzDao clazzDao = DBHelper.getInstance().getClazzDao();
        clazzDao.insertOrReplaceInTx(clazzList);

        JSONArray babys = data.getJSONArray("babys");
        List<Baby> babyList = JSON.parseArray(babys.toJSONString(), Baby.class);
        logger.debug("babyList =>" + babyList.size());
        BabyDao babyDao = DBHelper.getInstance().getBabyDao();
        CustodyDao custodyDao = DBHelper.getInstance().getCustodyDao();
        BabyCustodyDao babyCustodyDao = DBHelper.getInstance().getBabyCustodyDao();
        babyDao.insertOrReplaceInTx(babyList);

        List<Custody> custodyList = new ArrayList<>();
        List<BabyCustody> babyCustodyList = new ArrayList<>();
        for (Baby baby : babyList) {
            custodyList.addAll(baby.getCustodys());

            for (Custody custody : baby.getCustodys()) {
                BabyCustody babyCustody = new BabyCustody();
                babyCustody.setBabyId(baby.getId());
                babyCustody.setCustodyId(custody.getId());
                babyCustodyList.add(babyCustody);
            }
            loadImage(baby.getHead());
        }
        custodyDao.insertOrReplaceInTx(custodyList);
        babyCustodyDao.insertOrReplaceInTx(babyCustodyList);
    }

    private void loadImage(String head) {
        ImageLoader.getInstance().loadImage(head, null);
    }

}
